package api

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"hcy-api/lib/http"
	"hcy-api/structs/enum"
	"hcy-api/structs/tables"
	"hcy-api/structs/vap"
	"vap/global"
	dao2 "vap/module/dao"
	"vap/module/service"
)

var ClusterApi = new(clusterApi)

type clusterApi struct {
}

func (a *clusterApi) GetIssueAppInfo(c *gin.Context) {
	in := struct {
		Id int64 `uri:"id"`
	}{}
	if err := c.ShouldBindUri(&in); err != nil {
		http.BadWithParamsError(c, err)
		return
	}
	m, err := dao2.SessionRepository.FindAppIssueById(in.Id)
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.Ok(c, m)
}

func (a *clusterApi) GetInstallAppList(c *gin.Context) {
	in := struct {
		Id int64 `uri:"id"`
	}{}
	if err := c.ShouldBindUri(&in); err != nil {
		http.BadWithParamsError(c, err)
		return
	}
	li, err := dao2.HostRepository.FindInstallAppList(in.Id)
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.Ok(c, li)
}

func (a *clusterApi) TrimHostArgus(c *gin.Context) {
	var in vap.TrimHostDto
	if err := c.ShouldBindJSON(&in); err != nil {
		http.BadWithParamsError(c, err)
		return
	}
	var (
		old tables.VapHost
		err error
	)
	if old, err = dao2.HostRepository.FindHostById(in.HostId); err != nil {
		http.BadWithDB(c, err)
		return
	}
	//old.GuaPort = in.GuaPort
	//old.GuaIp = in.GuaIp
	//old.GuaProtocol = in.GuaProtocol
	if err = dao2.HostRepository.UpdateHostById(&old); err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.OK204(c)
}

func (a *clusterApi) UpdateHostAppList(c *gin.Context) {
	var in vap.UpdateHostAppDto
	if err := c.ShouldBindJSON(&in); err != nil {
		http.BadWithParamsError(c, err)
		return
	}
	err := service.ClusterService.UpdateHostAppList(in.HostId, in.IconPath)
	if err != nil {
		http.BadWithCode(c, enum.ErrorMap.SendHostInstructErr)
		return
	}
	http.OK204(c)
}

func (a *clusterApi) AddCluster(c *gin.Context) {
	var in vap.AddClusterDto
	if err := c.ShouldBindJSON(&in); err != nil {
		http.BadWithParamsError(c, err)
		return
	}
	self := http.GetCurrentUser(c)
	clusterId, err := service.ClusterService.AddCluster(in, self)
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.Ok(c, fmt.Sprintf("%d", clusterId))
}

func (a *clusterApi) ClusterList(c *gin.Context) {
	var li []tables.VapCluster
	err := global.DB.Model(&tables.VapCluster{}).Find(&li).Error
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.Ok(c, li)
}

func (a *clusterApi) DeleteCluster(c *gin.Context) {
	in := struct {
		Id int64 `uri:"id"`
	}{}
	if err := c.ShouldBindUri(&in); err != nil {
		http.BadWithParamsError(c, err)
		return
	}
	err := global.DB.Transaction(func(tx *gorm.DB) error {
		err := tx.Where(&tables.VapCluster{Id: in.Id}).Delete(&tables.VapCluster{}).Error
		if err != nil {
			return err
		}
		err = tx.Model(&tables.VapHost{}).Where(&tables.VapHost{ClusterID: in.Id}).Update("cluster_id", 0).Error
		return err
	})
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.OK204(c)
}

func (a *clusterApi) HostList(c *gin.Context) {
	li, _, err := dao2.HostRepository.FindHostAll()
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.Ok(c, li)
}

func (a *clusterApi) GetClusterHost(c *gin.Context) {
	in := struct {
		Id int64 `uri:"id"`
	}{}
	if err := c.ShouldBindUri(&in); err != nil {
		http.BadWithParamsError(c, err)
		return
	}
	li, err := service.ClusterService.GetHostListByClusterId([]int64{in.Id, 0})
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.Ok(c, li)
}

func (a *clusterApi) DeleteHost(c *gin.Context) {
	in := struct {
		Id int64 `uri:"id"`
	}{}
	if err := c.ShouldBindUri(&in); err != nil {
		http.BadWithParamsError(c, err)
		return
	}
	err := global.DB.Where(&tables.VapHost{Id: in.Id}).Delete(&tables.VapHost{}).Error
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.OK204(c)
}

func (a *clusterApi) BindHost(c *gin.Context) {
	var in vap.ClusterBindHostsDto
	if err := c.ShouldBindJSON(&in); err != nil {
		http.BadWithParamsError(c, err)
		return
	}
	err := global.DB.Transaction(func(tx *gorm.DB) error {
		err := tx.Model(&tables.VapHost{}).Where("cluster_id = ?", in.ClusterId).
			Update("cluster_id", 0).Error
		if err != nil {
			return err
		}
		return tx.Model(&tables.VapHost{}).Where("id in ?", in.HostIds).Update("cluster_id", in.ClusterId).Error
	})
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.OK204(c)
}

func (a *clusterApi) IssueApp(c *gin.Context) {
	var in vap.IssueAppDto
	if err := c.ShouldBindJSON(&in); err != nil {
		http.BadWithParamsError(c, err)
		return
	}
	err := service.ClusterService.IssueApp(in)
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.OK204(c)
}

func (a *clusterApi) DeleteApp(c *gin.Context) {
	in := struct {
		Id int64 `uri:"id"`
	}{}
	if err := c.ShouldBindUri(&in); err != nil {
		http.BadWithParamsError(c, err)
		return
	}
	err := global.DB.Transaction(func(tx *gorm.DB) error {
		err := tx.Model(&tables.VapAppIssue{}).Where(&tables.VapAppIssue{Id: in.Id}).Delete(&tables.VapAppIssue{}).Error
		return err
	})
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.OK204(c)
}

func (a *clusterApi) AppList(c *gin.Context) {
	in := struct {
		Name string `form:"name"`
	}{}
	if err := c.ShouldBindQuery(&in); err != nil {
		http.BadWithParamsError(c, err)
		return
	}
	li, err := service.ClusterService.AppList(in.Name)
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.Ok(c, li)
}
